using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VoxelEngine;
using VoxelEngine.Utils;

namespace VoxelGame.Character
{
	public class CharacterToolDrill : CharacterTool
	{
		[SerializeField]
		protected string _interactLoopAnimation = "loop";

		[SerializeField]
		private AudioClip _drillStartingSound;

		[SerializeField]
		private AudioClip _drillingSound;

		private bool _introAnimationPlayed;

		public override bool CanStartOperation(bool waitHalfAnimDuration = false)
		{
			return !_hasOperationStarted;
		}

		public override void PlayLongPressBeginAnimation()
		{
			StopCoroutine(PlayAsync());
			StartCoroutine(PlayAsync());
			SoundManager.Instance.PlaySoundEffect(_drillStartingSound, 0.5f);
		}

		public override void StopLongPressBeginAnimation()
		{
			StopCoroutine(PlayAsync());
			SoundManager.Instance.StopSFX(_drillingSound);
			_animation.CrossFade(_idleAnimation);
		}

		public override IEnumerator DestroyBlock(VoxelEngine.World world, Block selectedBlock, Action<Dictionary<BlockType, int>> onBlocksDestroyed, byte blockLight = 0)
		{
			_hasOperationStarted = true;
			Dictionary<BlockType, int> blocksDestroyed = new Dictionary<BlockType, int>();
			bool success = false;
			Action<BlockType> onBlockDestroyed = delegate(BlockType blockType)
			{
				if (!blocksDestroyed.ContainsKey(blockType))
				{
					blocksDestroyed[blockType] = 1;
				}
				else
				{
					Dictionary<BlockType, int> dictionary;
					BlockType key;
					(dictionary = blocksDestroyed)[key = blockType] = dictionary[key] + 1;
				}
				success = true;
			};
			Vector3i centerWorldPos = default(Vector3i);
			centerWorldPos.x = selectedBlock._wx;
			centerWorldPos.y = selectedBlock._wy;
			centerWorldPos.z = selectedBlock._wz;
			Vector3 normalized = base.transform.parent.parent.forward.normalized;
			float xAlignment = Mathf.Abs(normalized.x);
			Vector3 normalized2 = base.transform.parent.parent.forward.normalized;
			float yAlignment = Mathf.Abs(normalized2.y);
			Vector3 normalized3 = base.transform.parent.parent.forward.normalized;
			float zAlignment = Mathf.Abs(normalized3.z);
			if (xAlignment >= yAlignment && xAlignment >= zAlignment)
			{
				for (int i = centerWorldPos.z - 1; i <= centerWorldPos.z + 1; i++)
				{
					for (int j = centerWorldPos.y - 1; j <= centerWorldPos.y + 2; j++)
					{
						Block block = world[centerWorldPos.x, j, i];
						Destroy(world, block, onBlockDestroyed);
					}
				}
			}
			else if (zAlignment >= yAlignment && zAlignment >= xAlignment)
			{
				for (int k = centerWorldPos.x - 1; k <= centerWorldPos.x + 1; k++)
				{
					for (int l = centerWorldPos.y - 1; l <= centerWorldPos.y + 2; l++)
					{
						Block block2 = world[k, l, centerWorldPos.z];
						Destroy(world, block2, onBlockDestroyed);
					}
				}
			}
			else if (yAlignment >= xAlignment && yAlignment >= zAlignment)
			{
				for (int m = centerWorldPos.x - 1; m <= centerWorldPos.x + 1; m++)
				{
					for (int n = centerWorldPos.z - 1; n <= centerWorldPos.z + 1; n++)
					{
						Block block3 = world[m, centerWorldPos.y, n];
						Destroy(world, block3, onBlockDestroyed);
					}
				}
			}
			if (success)
			{
				_particle.Play();
				SoundManager.Instance.PlaySoundEffect(_drillingSound, 0.05f);
				ChunkRenderer.UpdateHeightMap(world, centerWorldPos, 7);
				ChunkRenderer.LightningFloodArea(world, centerWorldPos, 7);
				_soundController.PlayDestroyBlock();
				onBlocksDestroyed.Fire(blocksDestroyed);
			}
			yield return new WaitForSeconds(0.3f);
			_hasOperationStarted = false;
		}

		private void Destroy(VoxelEngine.World world, Block block, Action<BlockType> onBlockDestroyed)
		{
			if (block != null && block.IsSolid() && !block.Indestructible())
			{
				BlockType type = block.Type;
				block.Destroy(51);
				Vector3i worldPosition = default(Vector3i);
				worldPosition.x = block._wx;
				worldPosition.y = block._wy;
				worldPosition.z = block._wz;
				world.RefreshNeighborChunksIfNeeded(worldPosition);
				onBlockDestroyed.Fire(type);
			}
		}

		private IEnumerator PlayAsync()
		{
			_animation.Stop();
			_animation.Play(_interactAnimation);
			while (_animation[_interactAnimation].normalizedTime < 0.9f)
			{
				yield return null;
			}
			_animation.CrossFade(_interactLoopAnimation, 0.2f);
		}
	}
}
